/*
 * ThreadLocalPtr.h
 *
 *	Author: stravant
 *	Description:
 *		
 */

#ifndef THREADLOCALPTR_H_
#define THREADLOCALPTR_H_

#include "../core/Platform.h"

#if defined(OS_POSIX)
#include <pthread.h>
#endif

namespace priv {

class ThreadPlatform {
public:
#if defined(OS_POSIX)
	typedef pthread_key_t SlotType;
#elif defined(OS_WIN)
	typedef unsigned long SlotType;
#endif
	static void AllocSlot(SlotType& slot);
	static void FreeSlot(SlotType& slot);
	static void* GetSlotValue(SlotType& slot);
	static void SetSlotValue(SlotType& slot, void* value);
};

}

template <class T>
class ThreadLocalPtr {
public:
	ThreadLocalPtr() {
		priv::ThreadPlatform::AllocSlot(mSlot);
	}
	~ThreadLocalPtr() {
		priv::ThreadPlatform::FreeSlot(mSlot);
	}

	T* get() const {
		return static_cast<T*>(priv::ThreadPlatform::GetSlotValue(
				const_cast<priv::ThreadPlatform::SlotType&>(mSlot)));
	}
	void set(T* value) {
		priv::ThreadPlatform::SetSlotValue(mSlot, value);
	}
private:
	priv::ThreadPlatform::SlotType mSlot;
};

#endif /* THREADLOCALPTR_H_ */
